#include "TaskQueue.h"
#include <iostream>

using std::cout;
using std::endl;
using std::unique_lock;

using ElemType = function<void()>;
TaskQueue::TaskQueue(size_t capa)
: _capacity(capa)
, _que()
, _notEmpty()
, _notFull()
, _mutex()
, _wakeFlag(true)
{

}

TaskQueue::~TaskQueue()
{

}

bool TaskQueue::empty() const
{
    return _que.size() == 0;
}

bool TaskQueue::full() const
{
    return _capacity == _que.size();
}

void TaskQueue::push(ElemType &&taskcb)
{
    unique_lock<mutex> ul(_mutex);
    while(full())
    {
        _notFull.wait(ul);
    }
    _que.push(std::move(taskcb));
    _notEmpty.notify_one();
}

ElemType TaskQueue::pop()
{
    unique_lock<mutex> ul(_mutex);
    while(empty() && _wakeFlag)
    {
        _notEmpty.wait(ul);
    }

    if(_wakeFlag)
    {
        ElemType ret = _que.front();
        _que.pop();
        _notFull.notify_one();
        return ret;
    }
    else
    {
        return nullptr;
    }
}
void TaskQueue::wakeup()//唤醒_notEmpty处阻塞
{
    _wakeFlag = false;
    _notEmpty.notify_all();
}

